#ifndef _TlvMessage_h_
#define _TlvMessage_h_
////////////////////////////////////////////////////////////////////////////////
/// @file TlvMessage.h
/// @brief Short description .
///
/// A longer description 
/// 
///
/// Related Files: The implementation is in TlvMessage.cc.  
/// Other related files are: 
///
/// Maintained by: LTE eNB Callp Application Team
///
/// Copyright(c) 2009-2010 Nanocell, All Rights Reserved
///
/// CONFIDENTIALITY AND RESTRICTED USE
///
/// This software, including any software of third parties embodied herein,
/// contains information and concepts which are confidential to Nanocell 
/// and such third parties. This software is licensed for use
/// solely in accordance with the terms and conditions of the applicable
/// license agreement with Nanocell or its authorized distributor.
////////////////////////////////////////////////////////////////////////////////

#include <stdint.h>

//////////////////////////////////////////////////////////////////////////////
///
/// @class
///
///
///
//////////////////////////////////////////////////////////////////////////////

class TlvMessage
{
public:

    typedef uint8_t Protocol_t;
    typedef uint8_t Signal_t;
    typedef uint16_t Length_t;

    typedef uint8_t TlvTag_t;
    typedef uint16_t TlvLength_t;

    TlvMessage();
    TlvMessage(const Protocol_t protocolType, const Signal_t signalType);
    TlvMessage(const uint8_t* msgBuffer, const uint16_t length);
    virtual ~TlvMessage();

    Protocol_t getProtocolType() const;
    void setProtocolType(const Protocol_t protocolType);

    Signal_t getSignalType() const;
    void setSignalType(const Signal_t signalType);

    void getMsgBuffer(uint8_t*& msgBuffer, uint32_t& msgLength);

    void addTlv(const TlvTag_t tag, const int8_t value);
    bool getTlv(const TlvTag_t tag, int8_t& value, const int16_t instance = 1);

    void addTlv(const TlvTag_t tag, const uint8_t value);
    bool getTlv(const TlvTag_t tag, uint8_t& value, const int16_t instance = 1);

    void addTlv(const TlvTag_t tag, const int16_t value);
    bool getTlv(const TlvTag_t tag, int16_t& value, const int16_t instance = 1);

    void addTlv(const TlvTag_t tag, const uint16_t value);
    bool getTlv(const TlvTag_t tag, uint16_t& value, const int16_t instance = 1);

    void addTlv(const TlvTag_t tag, const int32_t value);
    bool getTlv(const TlvTag_t tag, int32_t& value, const int16_t instance = 1);
    
    void addTlv(const TlvTag_t tag, const uint32_t value);
    bool getTlv(const TlvTag_t tag, uint32_t& value, const int16_t instance = 1);

    void addTlv(const TlvTag_t tag, const uint64_t value);
    bool getTlv(const TlvTag_t tag, uint64_t& value);

    void addTlv(const TlvTag_t tag, const uint8_t* value, const TlvLength_t length);
    bool getTlv(const TlvTag_t tag, uint8_t*& value, TlvLength_t& length, const int16_t instance = 1);

    void addTlv(const TlvTag_t tag, const uint16_t* value, const TlvLength_t length);
    bool getTlv(const TlvTag_t tag, uint16_t*& value, TlvLength_t& length, const int16_t instance = 1);

    void addTlv(const TlvTag_t tag, const uint32_t* value, const TlvLength_t length);
    bool getTlv(const TlvTag_t tag, uint32_t*& value, TlvLength_t& length, const int16_t instance = 1);

private:
    static const int32_t HEADER_LENGTH = 4;
    static const int32_t PARM_HEADER_LENGTH = 3;
    static const int32_t BUFFER_INCREMENT_LENGTH = 256;

    void AllocBytes(const int32_t additionalBytes);
   
    void SetMsgLength(const Length_t length);
    void AddToMsgLength(const Length_t length);

    uint8_t* FindTlv(const TlvTag_t tag, const int16_t instance = 1);

    uint8_t* buffer_;
    uint16_t bufferLength_;
    uint8_t* endOfMessage_;
};




#endif
